#!/usr/bin/python3
# -*- encoding: utf-8 -*-
'''
@File        :超级鹰 Testy.py
@Time        :2020/08/30 10:47:56
@Author      :hejiang
@Software    :vsCode
'''

import time, requests, base64
from io import BytesIO
from PIL import Image
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import chaojiying
from chaojiying import Chaojiying_Client

# 注册超级鹰，进入页面生成软件id
CHAOJIYING_USERNAME = 'h521822'
CHAOJIYING_PASSWORD = 'hj123456'
CHAOJIYING_SOFT_ID = '794d92b4ae80aff7b183e1c6c260d553'
CHAOJIYING_KIND_FIVE = 9103
DATA_TEXT = '小米科技'


class CrackTouClick():
    def __init__(self):
        self.url = 'http://cpquery.cnipa.gov.cn/'
        # self.url = 'https://www.baidu.com/'
        self.browser = webdriver.Chrome(
            executable_path='D:\chrome\chromedriver.exe')
        # self.wait = WebDriverWait(self.browser, 20)
        # self.chaojiying = Chaojiying_Client(
        #     'h521822', 'hj123456',
        #     '794d92b4ae80aff7b183e1c6c260d553')  #用户中心>>软件ID 生成一个替换 96001

    # def __del__(self):
    #     self.browser.close()

    def open(self):
        """
        打开网页输入用户名密码
        :return: None
        """
        self.browser.get(self.url)

    def text_input(self):
        '''
        输入查询
        :return:
        '''
        input = self.wait.until(
            EC.presence_of_element_located((By.ID, 'keyword')))
        return input

    def get_touclick_button(self):
        """
        获取初始验证按钮
        :return:
        """
        time.sleep(3)
        button = self.wait.until(
            EC.element_to_be_clickable((By.ID, 'btn_query')))
        return button

    def get_touclick_element(self):
        """
        获取验证图片对象
        :return: 图片对象，图片链接
        """
        element = self.wait.until(
            EC.presence_of_element_located(
                (By.CLASS_NAME, 'geetest_item_img')))
        url_http = element.get_attribute('src')
        #print(url_http)
        return element, url_http

    def get_points(self, captcha_result):
        """
        解析识别结果
        :param captcha_result: 识别结果
        :return: 转化后的结果
        """
        groups = captcha_result.get('pic_str').split('|')
        locations = [[int(number) for number in group.split(',')]
                     for group in groups]
        return locations

    def touch_click_words(self, locations):
        """
        点击验证图片
        :param locations: 点击位置
        :return: None
        """
        for location in locations:
            print(location)
            element, url_http = self.get_touclick_element()
            ActionChains(self.browser).move_to_element_with_offset(
                element, location[0], location[1]).click().perform()
            time.sleep(0.5)

    def touch_click_verify(self):
        """
        点击验证按钮
        :return: None
        """
        button = self.wait.until(
            EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_commit_tip')))
        button.click()

    def request_download(self, IMAGE_URL):
        '''
        获取图片链接转换字节流，传入超级鹰
        :return:
        '''
        r = requests.get(IMAGE_URL)
        res = requests.get(IMAGE_URL,
                           stream=True)  # 获取字节流最好加stream这个参数,原因见requests官方文档

        byte_stream = BytesIO(res.content)  # 把请求到的数据转换为Bytes字节流

        roiImg = Image.open(byte_stream)  # Image打开Byte字节流数据
        # roiImg.show()   #  弹出 显示图片
        imgByteArr = BytesIO()  # 创建一个空的Bytes对象

        roiImg.save(imgByteArr, format='PNG')  # PNG就是图片格式，我试过换成JPG/jpg都不行

        imgByteArr = imgByteArr.getvalue()  # 这个就是保存的图片字节流
        with open('img.png', 'wb') as f:
            f.write(r.content)

        return imgByteArr

    # 主函数
    def crack(self):
        try:
            """
            破解入口
            :return: None
            """
            self.open()
            time.sleep(0.5)
            input = self.text_input()
            input.send_keys(DATA_TEXT)
            # 点击验证按钮
            button = self.get_touclick_button()
            button.click()
            time.sleep(3)
            # 获取原图地址，保存验证码图片
            element, url_http = self.get_touclick_element()
            img = self.request_download(url_http)
            # 识别验证码
            result = self.chaojiying.post_pic(img, CHAOJIYING_KIND_FIVE)
            print(result)
            locations = self.get_points(result)
            self.touch_click_words(locations)
            self.touch_click_verify()
            # 判定是否成功
            success = self.wait.until(
                EC.text_to_be_present_in_element(
                    (By.CLASS_NAME, 'ads-sci-title'), '信息分类'))
            print(success)
            time.sleep(1)
            print('验证成功')

        except Exception as e:
            print(e)
            print('失败，再次测试')
            self.crack()


if __name__ == '__main__':
    crack = CrackTouClick()
    crack.open()
    # crack.crack()